/**
 * 版权所有(C)，上海勾芒信息科技，2017，所有权利保留。
 * 
 * 项目名：	cards-web
 * 文件名：	CustomApplicationContextInitializer.java
 * 模块说明：	
 * 修改历史：
 * 2017年6月13日 - Debenson - 创建。
 */
package com.alex.insistence.web.context;

import java.io.IOException;

/** 定制ApplicationContextInitializer。
 * 
 * <pre>
 * Inject a property file into the Spring Environment. This is needed if you want to use properties from a file while importing xml in Spring managed beans xml files, like so:
 * 
 * <beans>
 *     <import resource="com/bank/service/${customer}-config.xml"/>
 * </beans>
 * The variable ${customer} should now be read from a variable.
 * </pre>
 * 
 * @author Debenson
 * @since 0.1
 */
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.io.support.ResourcePropertySource;

/**
 * @author Debenson
 * @since 0.1
 */
public class CustomApplicationContextInitializer
    implements ApplicationContextInitializer<ConfigurableApplicationContext> {
  private static final Logger logger = LoggerFactory
      .getLogger(CustomApplicationContextInitializer.class);

  private final static String PROPERTIES_FILE_LOAD_ORDER_FIRST = "FIRST";
  private final static String PROPERTIES_FILE_LOAD_ORDER_LAST = "LAST";

  /**
   * Reminder: Document this in the applications web.xml or other Application
   * Container.
   */
  private final static String PROPERTIES_FILE_LOAD_ORDER_DEFAULT = PROPERTIES_FILE_LOAD_ORDER_FIRST;

  @Override
  public void initialize(ConfigurableApplicationContext applicationContext) {
    ConfigurableEnvironment environment = applicationContext.getEnvironment();

    String propertiesFilePath = environment.getProperty("propertiesFile");
    String propertiesFileLoadOrder = getPropertiesFileLoadOrderFrom(environment);

    try {
      MutablePropertySources propertySources = environment.getPropertySources();
      if (propertiesFileLoadOrder.equalsIgnoreCase(PROPERTIES_FILE_LOAD_ORDER_LAST)) {
        propertySources.addLast(new ResourcePropertySource(propertiesFilePath));
      } else {
        propertySources.addFirst(new ResourcePropertySource(propertiesFilePath));
      }
      logger.info(String.format("'%s' loaded into ApplicationContext with load order '%s'",
          propertiesFilePath, propertiesFileLoadOrder));
    } catch (IOException ioException) {
      logger.error(String.format(
          "Could not load '%s' with load order '%s' while trying to load into the ApplicationContext",
          propertiesFilePath, propertiesFileLoadOrder));
    }
  }

  private String getPropertiesFileLoadOrderFrom(final ConfigurableEnvironment environment) {
    String propertiesFileLoadOrder = environment.getProperty("propertiesFileLoadOrder");
    if (propertiesFileLoadOrder == null || propertiesFileLoadOrder.isEmpty()) {
      return PROPERTIES_FILE_LOAD_ORDER_DEFAULT;
    }
    if (!propertiesFileLoadOrder.equalsIgnoreCase(PROPERTIES_FILE_LOAD_ORDER_FIRST)
        && !propertiesFileLoadOrder.equalsIgnoreCase(PROPERTIES_FILE_LOAD_ORDER_LAST)) {
      return PROPERTIES_FILE_LOAD_ORDER_DEFAULT;
    }
    return null;
  }
}
